/**
 *******************************************************************************
 * @file  main.c
 * @brief Main program.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2024-08-18       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "main.h"

// 用户引入的系统文件
#include <stdlib.h>
#include <string.h>

#include <ringbuffer.h>
// 用户引入的芯片库文件

// 用户环境头文件
#include "BspHelper.h"
#include "BufDef.h"
#include "BoardCommunicationModule.h"


/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/


/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/
bool run_healthy = true;

rt_thread_t debug_usart_tid;
rt_thread_t led_run_tid;
// 串口接收计数监听任务
rt_thread_t usart_transport_check_tid;
// GNSS任务
rt_thread_t gnss_task_tid;
// 加速度计相关的任务
rt_thread_t mems_task_tid;
rt_thread_t mems_rx_tid;
rt_thread_t mems_tx_tid;

/**
* bit0: 是否正常运行
* bit1: 是否在发送数据
*/
uint8_t led_status;
size_t led_busy_times;
/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/


// 调试串口发送函数
void Thread_Usart_Send(void *parmameter) {
  for (;;) {
    if (rt_mq_recv(&debug_usart_mq, debug_usart_tx_buf, sizeof(debug_usart_tx_buf), RT_WAITING_FOREVER) > 0) {
      GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
    }

    {// 控制台DMA发送
      DMA_SetSrcAddr(CM_DMA1, DMA_CH0, (uint32_t) debug_usart_tx_buf);

      DMA_SetTransCount(CM_DMA1, DMA_CH0, rt_strlen(debug_usart_tx_buf));

      (void) DMA_ChCmd(CM_DMA1, DMA_CH0, ENABLE);

      USART_FuncCmd(CM_USART3, USART_TX, ENABLE);
      rt_err_t result = rt_sem_take(debug_usart_sem, 500);
      if (result != RT_EOK) {
        GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
      }
      SWDT_FeedDog();
    }// 控制台DMA发送
  }  // 发送循环
}// 调试串口发送函数

// Led运行函数
void Thread_Led_Run(void *parmameter) {
  led_status = 0x01;
  SWDT_FeedDog();

  {
    // 初始引脚状态。取决于初始状态的高低电平哪个是灭
    GPIO_ResetPins(LED_RUN_PORT, LED_RUN_PIN);
	GPIO_ResetPins(LED_ERR_PORT, LED_ERR_PIN);
  }

  for (;;) {
    {                                // 闪烁第一段
      if ((led_status & 0x01) != 0) {// led bsp运行
        GPIO_TogglePins(LED_RUN_PORT, LED_RUN_PIN);
      }// led bsp运行
    }  // 闪烁第一段
    rt_thread_mdelay(50);

    {// 闪烁第二段
    }// 闪烁第二段
    rt_thread_mdelay(50);

    {// 闪烁第三段
    }// 闪烁第三段
    rt_thread_mdelay(50);

    {// 闪烁第四段
    }// 闪烁第四段
    rt_thread_mdelay(50);

    {// 闪烁第五段
    }// 闪烁第五段
    rt_thread_mdelay(50);

    {// 闪烁第六段
	  if ((led_status & 0x02) != 0) {// led bsp运行
        GPIO_TogglePins(LED_RUN_PORT, LED_RUN_PIN);
      }// led bsp运行
    }// 闪烁第六段
    rt_thread_mdelay(50);

    {// 闪烁第七段
    }// 闪烁第七段
    rt_thread_mdelay(50);

    {// 闪烁第八段
    }// 闪烁第八段
    rt_thread_mdelay(50);

    {// 闪烁第九段
    }// 闪烁第九段
    rt_thread_mdelay(50);

    {// 闪烁第十段
    }// 闪烁第十段
    rt_thread_mdelay(50);
    SWDT_FeedDog();

    {                                // 闪烁第十一段
      if ((led_status & 0x01) != 0) {// led bsp运行
        GPIO_TogglePins(LED_RUN_PORT, LED_RUN_PIN);
      }// led bsp运行
    }  // 闪烁第十一段
    rt_thread_mdelay(50);

    {// 闪烁第十二段
    }// 闪烁第十二段
    rt_thread_mdelay(50);

    {// 闪烁第十三段
    }// 闪烁第十三段
    rt_thread_mdelay(50);

    {// 闪烁第十四段
    }// 闪烁第十四段
    rt_thread_mdelay(50);

    {// 闪烁第十五段
    }// 闪烁第十五段
    rt_thread_mdelay(50);

    {// 闪烁第十六段
	  if ((led_status & 0x02) != 0) {// led bsp运行
        GPIO_TogglePins(LED_RUN_PORT, LED_RUN_PIN);
      }// led bsp运行
    }// 闪烁第十六段
    rt_thread_mdelay(50);

    {// 闪烁第十七段
    }// 闪烁第十七段
    rt_thread_mdelay(50);

    {// 闪烁第十八段
    }// 闪烁第十八段
    rt_thread_mdelay(50);

    {// 闪烁第十九段
    }// 闪烁第十九段
    rt_thread_mdelay(50);

    {// 闪烁第二十段
    }// 闪烁第二十段
    rt_thread_mdelay(50);
    SWDT_FeedDog();

    {// 对于该清位的地方清位
		if (led_busy_times > 0){ // 处理忙碌状态
			led_busy_times--;
			led_status |= (1 << 1);
		}else{
			led_status &= 0xFD;
		} // 处理忙碌状态

        // 处理网络状态
//		if (lte_connected == RT_EOK && mqtt1_status == 2) {
//			led_status |= (1 << 2);
//			led_status |= (1 << 3);
//		} else if (lte_connected == RT_EOK && mqtt1_status != 2){
//			led_status |= (1 << 2);
//			led_status &= 0xF7;
//		} else {
//			led_status &= 0xF3;
//		}
    }// 对于该清位的地方清位
  }  // 发送循环
}// Led运行函数

int32_t main_loop(void) {
  SWDT_FeedDog();
  rt_thread_mdelay(500);
  SWDT_FeedDog();
  rt_thread_mdelay(500);
  rt_kprintf("test debug usart t3!\n");
  rt_kprintf("get ms: %d\n", ms_cnt);
	
  {// 控制台DMA发送
	  GPIO_SetPins(GPIO_PORT_D, GPIO_PIN_13);
	  
      DMA_SetSrcAddr(CM_DMA2, DMA_CH1, (uint32_t) usart_9_tx_msq_buf);

      DMA_SetTransCount(CM_DMA2, DMA_CH1, rt_strlen((char*)usart_9_tx_msq_buf));

      (void) DMA_ChCmd(CM_DMA2, DMA_CH1, ENABLE);

      USART_FuncCmd(CM_USART9, USART_TX, ENABLE);
      rt_err_t result = rt_sem_take(rs485_3_usart_tx_sem, 500);
      if (result != RT_EOK) {
        GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
      }
	  rt_thread_mdelay(3);
	  GPIO_ResetPins(GPIO_PORT_D, GPIO_PIN_13);
	  rt_kprintf("usart9 send successful!\n");
	  if (rt_mq_recv(&rs485_3_usart_rx_mq, usart_9_rx_app_buf, sizeof(usart_9_rx_app_buf), RT_WAITING_FOREVER) > 0) {
        GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
	  }else {
		  rt_kprintf("get data: %d\nget str: %s\n", 
		  usart_9_rx_app_buf[0] * 0x1000000 + usart_9_rx_app_buf[1] * 0x10000 + usart_9_rx_app_buf[2] * 0x100 + usart_9_rx_app_buf[3],
		  &(usart_9_rx_app_buf[4]));
	  }
      SWDT_FeedDog();
	  rt_thread_yield();
    }// 控制台DMA发送

  if (!run_healthy) {
    return 1;
  }


  return 0;
}

/**
 * @brief  Main function of the project
 * @param  None
 * @retval int32_t return value, if needed
 */
int32_t main(void) {
	strcpy((char*)usart_9_tx_msq_buf, "test usart9!\n");
  //char* buf_test = (char*)0x100000;
  //strcpy(buf_test, "buf_test1: 1234\n");
  //  DDL_DelayMS(250);
  //  strcpy(buf_test, "buf_test2: 7890\n");
  //  rt_kprintf(buf_test);
	
  // 初始化板子。这里改为由rt-thread初始化
  //Bsp_Init();
  // 创建用于发送log的锁
  // 注意，sem不能在main函数被创建前创建。因为对象管理器还没被初始化。
  debug_usart_sem = rt_sem_create("debug_usart", 0, RT_IPC_FLAG_PRIO);
  if (debug_usart_sem == RT_NULL) {
    for (;;) {
      GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
      DDL_DelayMS(250);
      GPIO_ResetPins(LED_ERR_PORT, LED_ERR_PIN);
      DDL_DelayMS(250);
      GPIO_SetPins(LED_ERR_PORT, LED_ERR_PIN);
      DDL_DelayMS(250);
      GPIO_ResetPins(LED_ERR_PORT, LED_ERR_PIN);
      DDL_DelayMS(250);
    }
  }
  // 创建用于发送log的锁
  
  // 初始化RS485-3运行环境
  Init_Rs485_3_Usart_Env();
  // 用于创建没有接收定时器的串口接收定时信号
  usart_transport_check_sem = rt_sem_create("usart_transport_check_sem", 0, RT_IPC_FLAG_PRIO);
  // 用于创建没有接收定时器的串口接收定时信号
  SWDT_FeedDog();

  // 初始化log发送线程
  debug_usart_tid = rt_thread_create("Thread_Usart_Send",
                                     Thread_Usart_Send, RT_NULL,
                                     THREAD_STACK_SIZE,
                                     THREAD_PRIORITY, THREAD_TIMESLICE);

  if (debug_usart_tid != RT_NULL) {
    rt_thread_startup(debug_usart_tid);
  }
  SWDT_FeedDog();

  // 初始化led闪烁线程
  led_run_tid = rt_thread_create("Thread_Led Run",
                                 Thread_Led_Run, RT_NULL,
                                 THREAD_STACK_SIZE,
                                 THREAD_PRIORITY, THREAD_TIMESLICE);
  if (led_run_tid != RT_NULL) {
    rt_thread_startup(led_run_tid);
  }
  
  // 初始化串口接收计数任务线程
  usart_transport_check_tid = rt_thread_create("usart_transport_check_tid Run",
                                 Check_Usart_Receive_Data_Task, RT_NULL,
                                 THREAD_STACK_SIZE,
                                 THREAD_PRIORITY, THREAD_TIMESLICE);
  if (usart_transport_check_tid != RT_NULL) {
    rt_thread_startup(usart_transport_check_tid);
  }

  for (int index = 0; index < CONFIG_ARRAY_SIZE; index++) {
    rt_kprintf("get key: %s, value: %s\n", device_address[index].key, device_address[index].value);
    rt_thread_mdelay(1);
  }
  SWDT_FeedDog();


  // 启动毫秒计数器
  ms_cnt = 0;
  TMR2_Start(CM_TMR2_1, TMR2_CH_A);
  TMR2_Start(CM_TMR2_2, TMR2_CH_A);



  rt_kprintf("get type size: %d\n", sizeof(I2c_Data_Task_Def));

  {// 测试sdram
//    BSP_Sdram_GetMemInfo(&m_u32StartAddr, &m_u32ByteSize);
//    rt_kprintf("Memory start address: 0x%.8x \n", (unsigned int) m_u32StartAddr);
//    rt_kprintf("Memory end   address: 0x%.8x \n", (unsigned int) (m_u32StartAddr + m_u32ByteSize - 1UL));
//    rt_kprintf("Memory size  (Bytes): 0x%.8x \n\n", (unsigned int) m_u32ByteSize);

//    SWDT_FeedDog();
//    rt_thread_yield();

    //__attribute__((at(0x80004000))) char test_reg1[512];
//    char *test_reg1 = rt_mp_alloc(&sdram1_mp, 500);
//    for (int index = 0; index < 3; index++) {
//      memset(test_reg1, 0, 512);
//      SWDT_FeedDog();
//      rt_thread_yield();

//      char *test_str1 = "hello mem!";
//      char *test_str2 = "check mem!";
//      char *test_str3 = "write mem!";
//      memcpy(&test_reg1, &test_str1, 10);
//      rt_kprintf("set mem reg: %s\n", test_reg1);
//      rt_thread_yield();

//      memcpy(&test_reg1, &test_str2, 10);
//      rt_kprintf("set mem reg: %s\n", test_reg1);
//      rt_thread_yield();

//      memcpy(&test_reg1, &test_str3, 10);
//      rt_kprintf("set mem reg: %s\n", test_reg1);
//      rt_thread_yield();
//      SWDT_FeedDog();
//    }

    // 初始化测试数组
    //__attribute__((at(0x80009000))) uint8_t data_array[512];
    //uint8_t *data_array = rt_mp_alloc(&sdram1_mp, 500);
    //    for (int index = 0; index < 512; index++) {
    //      data_array[index] = index;
    //      //SWDT_FeedDog();
    //      rt_thread_yield();
    //    }
    //data_array[0] = 0x12;
    //rt_kprintf("read mem data: \nindex: 0x%02X, value: 0x%02X\n", 0, data_array[0]);

    //    	for (int index =0; index<64; index++){
    //    		rt_kprintf("read mem data: \nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\nindex: 0x%02X, value: 0x%02X\n",
    //    		index*8, data_array[index*8],
    //    		index*8 + 1, data_array[index*8 + 1],
    //    		index*8 + 2, data_array[index*8 + 2],
    //    		index*8 + 3, data_array[index*8 + 3],
    //    		index*8 + 4, data_array[index*8 + 4],
    //    		index*8 + 5, data_array[index*8 + 5],
    //    		index*8 + 6, data_array[index*8 + 6],
    //    		index*8 + 7, data_array[index*8 + 7]);
    //    		rt_thread_mdelay(1);
    //    	    SWDT_FeedDog();
    //    	}

    //uint8_t *ring_buf_data = rt_mp_alloc(&sdram1_mp, 500);
    uint8_t ring_buf_data[256];
    rt_memset(ring_buf_data, 0, 256);
    struct rt_ringbuffer test_rb;
    rt_ringbuffer_init(&test_rb, (uint8_t *) ring_buf_data, 256);
    char *ring_buf_test1 = "12345ring\n";
    uint8_t ring_buf_test2[10];
    rt_memcpy(ring_buf_test2, "empty buf\n", 10);
    rt_ringbuffer_put_force(&test_rb, (rt_uint8_t *) ring_buf_test1, 10);
    rt_kprintf("rnig buf size: %d\n", rt_ringbuffer_data_len(&test_rb));
    rt_ringbuffer_get(&test_rb, (rt_uint8_t *) ring_buf_test2, 10);
    rt_kprintf((char *) ring_buf_test2);
  }// 测试sdram


  /* Add your code here */
  for (;;) {// 任务主循环
    int res = main_loop();
    // 当返回值为正数时为标准退出程序。直接退出。为0时啥也不干。为负时有错且需要出发处理程序
    if (res > 0) {
      break;
    } else if (res < 0) {
      ;
    } else {
      ;
    }// min_loop返回值处理
  }  // 任务主循环
}

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
